<template>
	<view class="base">
		<view class="base-input">
			<view class="label" v-for="(value, index) in selectItems">
				{{value}}
				<view class="close" @click="closeHandle(index)">×</view>
			</view>
			<input class="input" type="text" v-model="inputValue" 
			@blur="blurHandle"
			:focus="autofocus" v-on:input="inputHandle($event.target.value)"
			 @confirm="confirmHandle" />
		</view>
		<view class="fuzzy-select load-select" v-if="isLoading">
			loading
		</view>

		<view class="fuzzy-select" v-else-if="isItemsEmpty || items && items.length > 0">
			<template v-if="isItemsEmpty">
				<view class="empty-tips">暂无数据</view>
			</template>
			<template v-else>
				<view class="item" v-for="(item,index) in items" :key="index" @click="clickHandle(item)">
					<view v-if="isSelected(item.value)">{{ item.label }}</view>
					<view v-else class="selected">{{ item.label }}</view>
				</view>
			</template>
		</view>

	</view>
</template>

<script>
	export default {
		model: {
			prop: 'modelValue',
			event: 'input'
		},
		data() {
			return {
				inputValue: '',
				items: [],
				autofocus: false,
				selectItems: [],
				throttleDelay: 300, // 节流延时
				throttleToggle: true,
				isLoading: false, // 加载列表
				isItemsEmpty: false // 控制列表为空时提示
			};
		},
		props: {
			modelValue: String,
			fetchSuggestions: Function
		},
		watch: {
			inputValue: function(oldValue) {
				let modelValue = this.getModelValue()
				if (this.handleType != 'click') {
					this.throttleGet(this.getSelectItems, 3000)()
				}
				if (oldValue == '') {
					this.hideSelect()
				}
			}
		},
		methods: {
			blurHandle() {
				// 输入框为空 隐藏下拉
				if(this.inputValue == '') {
					this.hideSelect()
				}
			},
			getModelValue() {
				let modelValue = this.selectItems.join(',')
				if (this.inputValue) {
					modelValue += (this.selectItems.length>0?',':'') + this.inputValue
				}
				return modelValue
			},
			isSelected(value) {
				let res = this.selectItems.indexOf(value) === -1
				return res
			},
			closeHandle(index) {
				this.autofocus = false
				this.selectItems.splice(index, 1)
				setTimeout(() => {
					this.autofocus = true
				}, 100)
			},
			// 点击赋值
			clickHandle(item) {
				this.autofocus = false
				this.handleType = 'click'
				this.selectItems.push(item.label)
				let modelValue = this.getModelValue()
				this.$emit('input', modelValue)
				this.$emit('change',item)
				setTimeout(() => {
					this.autofocus = true
				}, 100)
				// this.hideSelect() // 点击控制不显示列表
			},
			inputHandle(queryString) {
				this.handleType = 'input'
				this.$emit('input', queryString)
			},
			// 确认查询
			confirmHandle() {
				this.getSelectItems()
			},
			hideSelect() {
				this.isLoading = false
				this.isItemsEmpty = false
				this.items = []
			},
			// 节流：300ms后请求一次
			throttleGet(fn) {
				return () => {
					if (!this.throttleToggle) return;
					this.throttleToggle = false;
					setTimeout(() => {
						fn.apply(this);
						this.throttleToggle = true;
					}, this.throttleDelay);
				}
			},
			getSelectItems() {
				this.isLoading = true
				this.isItemsEmpty = false
				if (this.inputValue === '') {
					this.isLoading = false
					return
				}
				this.fetchSuggestions(this.inputValue, (items) => {
					this.items = []
					if (Array.isArray(items) && items.length > 0) {
						this.isLoading = false
						this.items = items.slice(0, 15);
					} else {
						this.isLoading = false
						this.isItemsEmpty = true
					}
				})
			}
		}
	}
</script>

<style scoped lang="scss">
	.base-input::-webkit-scrollbar {
		display: none;
		width: 0;
		height: 0;
	}

	.base {
		position: relative;

		.base-input {
			// display: inline-block;
			display: inline-flex;
			flex-direction: row;
			flex-wrap: wrap;
			width: 400rpx;
			padding: 2px 5px;
			border: 1px solid rgba(0, 0, 0, 0.1);
			background-size: 100% 100%;

			// overflow-x: scroll;
			.label {
				display: inline-flex;
				align-items: center;
				flex-shrink: 0;
				max-width: calc(100% - 11px);
				background-color: #f4f4f5;
				border-color: #e9e9eb;
				color: #909399;
				margin: 2px 6px 2px 6px;
				// height: 24px;
				padding: 2px 8px;
				line-height: 22px;
				box-sizing: border-box;


				.close {
					display: flex;
					flex-shrink: 0;
					align-items: center;
					justify-content: center;
					height: 16px;
					width: 16px;
					cursor: pointer;
					border-radius: 50%;
					color: #909399;
					text-align: center;
					font-size: 16px;
					line-height: 16px;
					vertical-align: middle;
					background-color: #c0c4cc;
					margin-left: 6px;
				}
			}

			.input {
				flex-grow: 1;
				width: 0rpx;
				min-width: 150rpx;
				margin: 2px 0 2px 6px;
			}
		}

		.load-select {
			display: flex;
			justify-content: center;
			align-items: center;
			padding: 15px 10px;
		}

		.fuzzy-select {
			background: #fff;
			width: 500rpx;
			max-height: 50vh;
			overflow-y: scroll;
			position: absolute;
			top: calc(100% + 10px);
			border: 1px solid rgba(0, 0, 0, 0.1);
			box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

			.empty-tips {
				padding: 15px 10px;
			}

			.item {
				line-height: 30px;
				padding: 10px 30px 10px 10px;
				border-bottom: 1px solid rgba(0, 0, 0, 0.1);
			}

			.selected {
				color: rgb(0, 178, 106);
			}

			.selected:after {
				position: absolute;
				right: 20px;
				line-height: 30px;
				content: "√";
				font-size: 12px;
				font-weight: 700;
			}

			.item::hover {}
		}
	}
</style>
